package handler

import (
	"context"
	"github.com/goccy/go-json"
	"go-likaladi-shop/common/base_global"
	"go-likaladi-shop/common/base_util"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/emptypb"
	"lw-shop/goods_service/model"
	"lw-shop/goods_service/proto"
)

// 商品分类->构建树节点分类
func (s *GoodsService) GetAllCategorysList(context.Context, *emptypb.Empty) (*proto.CategoryListResponse, error) {
	var categories []model.Category
	db := base_global.DB.Find(&categories)
	if db.Error != nil {
		return nil, base_util.GrpcError(db.Error)
	}

	// 构建根节点为 0（或 null）的分类树
	tree := buildCategoryTree(categories, 0)

	b, _ := json.Marshal(tree)
	return &proto.CategoryListResponse{Data: tree, JsonData: string(b)}, nil
}

func (s *GoodsService) DBQueryCategoryList(context.Context, *emptypb.Empty) (*proto.CategoryListResponse, error) {
	tree := dbCategoryTree(0)
	b, _ := json.Marshal(tree)
	return &proto.CategoryListResponse{Data: tree, JsonData: string(b)}, nil
}

// 获取⼦分类
func (s *GoodsService) GetSubCategory(ctx context.Context, req *proto.CategoryListRequest) (*proto.SubCategoryListResponse, error) {
	categoryListResponse := proto.SubCategoryListResponse{}
	var category model.Category
	//select * from category where id = req.id
	if result := base_global.DB.First(&category, req.Id); result.RowsAffected == 0 {
		return nil, base_util.LogicError("商品分类不存在")
	}

	categoryListResponse.Info = &proto.CategoryInfoResponse{
		Id:             category.ID,
		Name:           category.Name,
		ParentCategory: category.ParentCategoryID,
		Level:          category.Level,
		IsTab:          category.IsTab,
	}
	return nil, nil
}

func (s *GoodsService) CreateCategory(ctx context.Context, req *proto.CategoryInfoRequest) (*proto.CategoryInfoResponse, error) {
	category := model.Category{}
	category.Name = req.Name
	category.Level = req.Level
	if req.Level != 1 {
		category.ParentCategoryID = req.ParentCategory
	}
	category.IsTab = req.IsTab
	base_global.DB.Save(&category)
	return &proto.CategoryInfoResponse{Id: int32(category.ID)}, nil
}

func (s *GoodsService) DeleteCategory(ctx context.Context, req *proto.DeleteCategoryRequest) (*emptypb.Empty, error) {
	if result := base_global.DB.Delete(&model.Category{}, req.Id); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.NotFound, "商品分类不存在")
	}
	return &emptypb.Empty{}, nil
}

func (s *GoodsService) UpdateCategory(ctx context.Context, req *proto.CategoryInfoRequest) (*emptypb.Empty, error) {
	var category model.Category
	if result := base_global.DB.First(&category, req.Id); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.NotFound, "商品分类不存在")
	}
	if req.Name != "" {
		category.Name = req.Name
	}
	if req.ParentCategory != 0 {
		category.ParentCategoryID = req.ParentCategory
	}
	if req.Level != 0 {
		category.Level = req.Level
	}
	if req.IsTab {
		category.IsTab = req.IsTab
	}
	base_global.DB.Save(&category)
	return &emptypb.Empty{}, nil
}

func buildCategoryTree(categories []model.Category, parentID int32) []*proto.CategoryInfoResponse {
	var tree []*proto.CategoryInfoResponse
	for _, category := range categories {
		if category.ParentCategoryID == parentID {
			node := &proto.CategoryInfoResponse{
				Id:             category.ID,
				Name:           category.Name,
				ParentCategory: category.ParentCategoryID,
				Level:          category.Level,
				IsTab:          category.IsTab,
				SubCategories:  buildCategoryTree(categories, category.ID),
			}
			tree = append(tree, node)
		}
	}
	return tree
}

func dbCategoryTree(parentID int32) []*proto.CategoryInfoResponse {
	var categories []model.Category
	//select * from xx_table where parent_category_id = parentID
	result := base_global.DB.Where(&model.Category{ParentCategoryID: parentID}).Find(&categories)
	if result.RowsAffected == 0 {
		return nil
	}

	var tree []*proto.CategoryInfoResponse
	for _, category := range categories {
		node := &proto.CategoryInfoResponse{
			Id:             category.ID,
			Name:           category.Name,
			ParentCategory: category.ParentCategoryID,
			Level:          category.Level,
			IsTab:          category.IsTab,
			SubCategories:  dbCategoryTree(category.ID),
		}
		tree = append(tree, node)
	}
	return tree
}

// QueryCategoryByIds 根据传入的ID列表，批量查询分类信息。
// 若传入空的ID列表，则直接返回空切片，不执行数据库查询。
func QueryCategoryByIds(ids []int32) ([]*proto.CategoryInfoResponse, error) {
	// 判断ID列表是否为空，若为空直接返回空结果，避免不必要的数据库访问
	if len(ids) == 0 {
		return []*proto.CategoryInfoResponse{}, nil
	}

	// 定义用于存储数据库查询结果的实体切片
	var categories []model.Category
	if err := base_util.QueryByIds(ids, &categories); err != nil {
		return nil, err
	}

	// 定义结果切片，将数据库实体转换为 proto 响应结构
	var result []*proto.CategoryInfoResponse
	for _, category := range categories {
		result = append(result, &proto.CategoryInfoResponse{
			Id:             category.ID,               // 品牌ID
			Name:           category.Name,             // 品牌名称
			ParentCategory: category.ParentCategoryID, // 品牌LOGO
			Level:          category.Level,
			IsTab:          category.IsTab,
		})
	}

	// 返回转换后的结果集和nil错误
	return result, nil
}

func CategoryDBMap(ids []int32) (map[int32]*proto.CategoryInfoResponse, error) {
	categories, err := QueryCategoryByIds(ids)
	if err != nil {
		return nil, err
	}
	brandMap := base_util.SliceToMap(categories, func(obj *proto.CategoryInfoResponse) int32 {
		return obj.Id
	})
	return brandMap, nil
}
